home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / TEX-UTIL / DVIPS_55 / dvips / src / c / finclude < prev    next >
Text File  |  1994-05-06  |  9KB  |  334 lines

  1. /*
  2.  *  Code for allowing fonts to be used in PostScript files given via
  3.  *  `psfile=...'.
  4.  */
  5. #include "dvips.h" /* The copyright notice in that file is included too! */
  6. #include <ctype.h>
  7.  
  8. #ifndef SYSV
  9. extern char *strtok() ; /* some systems don't have this in strings.h */
  10. #endif
  11. #ifdef VMS
  12. #define getname vms_getname
  13. #endif
  14.  
  15.  
  16. /*
  17.  *   These are the external routines we call.
  18.  */ 
  19. #define atof(s) strtod(s,0)
  20. extern fontdesctype *newfontdesc() ;
  21. extern fontdesctype *matchfont() ;
  22. extern Boolean prescanchar() ;
  23. extern Boolean preselectfont() ;
  24. extern void scout(), error() ;
  25. extern void stringend() ;
  26. extern void cmdout() ;
  27. extern void numout() ;
  28. extern void lfontout() ;
  29. extern char *newstring() ;
  30. extern FILE *search() ;
  31. /*
  32.  *   These are the external variables we access.
  33.  */
  34. extern fontdesctype *curfnt ;
  35. extern fontdesctype *fonthead ;
  36. extern integer fontmem ;
  37. extern fontdesctype *fonthd[MAXFONTHD] ;
  38. extern int nextfonthd ;
  39. extern char *nextstring ;
  40. extern char xdig[256] ;
  41. extern real conv ;
  42. extern integer pagecost ;
  43. extern int actualdpi ;
  44. extern integer mag ;
  45. extern Boolean includesfonts ;
  46. /* extern char *figpath ; */
  47. /*
  48.  * Create a font descriptor for a font included in a psfile.  There will be
  49.  * no fontmaptype node for the resulting font descriptor until this font is
  50.  * encountered by fontdef() (if that ever happens).
  51.  */
  52. fontdesctype *
  53. ifontdef(name, area, scsize, dssize, scname)
  54. char *name, *scname, *area ;
  55. integer scsize, dssize ;
  56. {
  57.    fontdesctype *fp;
  58.  
  59.    fp = newfontdesc((integer)0, scsize, dssize, name, area);
  60.    fp->scalename = scname;
  61.    fp->next = fonthead ;
  62.    fonthead = fp ;
  63.    return fp;
  64. }
  65. /*
  66.  * When a font appears in an included psfile for the first time, this routine
  67.  * links it into the fonthd[] array.
  68.  */
  69. void
  70. setfamily(f)
  71. fontdesctype *f ;
  72. {
  73.    int i ;
  74.  
  75.    fontmem -= DICTITEMCOST;
  76.    for (i=0; i<nextfonthd; i++)
  77.       if (strcmp(f->name, fonthd[i]->name)==0
  78.             && strcmp(f->area, fonthd[i]->area)==0) {
  79.          f->nextsize = fonthd[i];
  80.          fonthd[i] = f;
  81.          return;
  82.       }
  83.    if (nextfonthd==MAXFONTHD)
  84.       error("! Too many fonts in included psfiles") ;
  85.    fontmem -= NAMECOST + strlen(f->name) + strlen(f->area) ;
  86.    fonthd[nextfonthd++] = f ;
  87.    f->nextsize = NULL ;
  88. }
  89. /*
  90.  * Convert file name s to a pair of new strings in the string pool.
  91.  * The first string is the original value of nextstring; the second
  92.  * string is the return value.
  93.  */
  94. char*
  95. getname(s)
  96. char *s ;
  97. {
  98.    char *a, *p, sav;
  99.  
  100.    a = NULL;
  101.    for (p=s; *p!=0; p++)
  102.       if (*p=='/')
  103.          a = p+1 ;
  104.    if (a==NULL) *nextstring++ = 0 ;
  105.    else {   sav = *a ;
  106.       *a = 0 ;
  107.       (void) newstring(s) ;
  108.       *a = sav ;
  109.       s = a ;
  110.    }
  111.    return newstring(s);
  112. }
  113. /*
  114.  * Mark character usage in *f based on the hexadicimal bitmap found in
  115.  * string s.  A two-digit offset separated by a colon gives the initial
  116.  * character code.  We have no way of knowing how many times each character
  117.  * is used or how many strings get created when showing the characters so
  118.  * we just estimate two usages per character and one string per pair of
  119.  * usages.
  120.  */
  121. void
  122. includechars(f, s)
  123. fontdesctype *f ;
  124. char *s ;
  125. {
  126.    int b, c, d ;
  127.    int l = strlen(s) ;
  128.  
  129.    if (l>0 && s[l-1]=='\n')
  130.       s[--l] = 0 ;
  131.    if (!isxdigit(s[0]) || !isxdigit(s[1]) || s[2]!=':'
  132.          || strspn(s+3,"0123456789ABCDEFabcdef") < l-3) {
  133.       fprintf(stderr, "%s\n", s) ;
  134.       error("Bad syntax in included font usage table") ;
  135.       return ;
  136.    }
  137.    c = (xdig[(int)(s[0])] << 4) + xdig[(int)(s[1])] ;
  138.    s += 2 ;
  139.    while (*++s) {
  140.       d = xdig[(int)*s] ;
  141.       for (b=8; b!=0; b>>=1) {
  142.          if ((d&b)!=0) {
  143.             pagecost ++ ;
  144.             (void) prescanchar(&f->chardesc[c]) ;
  145.          }
  146.          if (++c==256) return ;
  147.       }
  148.    }
  149. }
  150. /*
  151.  * String p should be start after the ":" in a font declaration of the form
  152. %*FONT: <tfm-name> <scaled-size> <design-size> <2-hex-digits>:<hex-string>
  153.  * where the sizes are floating-point numbers in units of PostScript points
  154.  * (TeX's "bp").  We update the data structures for the included font,
  155.  * charge fontmem for the VM used, and add to delchar if necessary.
  156.  * Note that the scaled size and the design size are multiplied by mag/1000.
  157.  * This is needed for the design size to undo the similar factor in conv since
  158.  * design sizes are not supposed to be affected by magnification.  Applying
  159.  * the magnification factor to the scaled size selects magnified fonts as is
  160.  * appropriate in the normal case where the included PostScript is scaled by
  161.  * mag/1000.  The definition of `fshow' in finclude.lpro unscales by `DVImag'
  162.  * to account for this.  We cannot change the font scaled size to account for
  163.  * options like `hscale=' because then the definition of `fshow' would have
  164.  * to change.
  165.  */
  166. void
  167. scan1fontcomment(p)
  168. char *p ;
  169. {
  170.    char *q, *name, *area;
  171.    char *scname;      /* location in buffer where we got scsize */
  172.    integer scsize, dssize;
  173.    fontdesctype *fptr;
  174.    real DVIperBP;
  175.  
  176.    DVIperBP = actualdpi/(72.0*conv) * (mag/1000.0);
  177.    p = strtok(p, " ");
  178.    if (p==NULL) return;
  179.    area = nextstring ;   /* tentatively in the string pool */
  180.    name = getname(p);
  181.    q = strtok((char *)0, " ");
  182.    if (p==NULL || (scsize=(integer)(atof(q)*DVIperBP))==0) {
  183.       fprintf(stderr, "%s\n",p);
  184.       error("No scaled size for included font");
  185.       nextstring = area ;   /* remove from string pool */
  186.       return;
  187.    }
  188.    scname = q;
  189.    q = strtok((char *)0, " ");
  190.    if (p==NULL || (dssize=(integer)(atof(q)*DVIperBP))==0) {
  191.       fprintf(stderr, "%s\n",p);
  192.       error("No design size for included font");
  193.       nextstring = area ;
  194.       return;
  195.    }
  196.    q = strtok((char *)0, " ");
  197.    fptr = matchfont(name, area, scsize, scname);
  198.    if (!fptr) {
  199.       fptr = ifontdef(name, area, scsize, dssize, newstring(scname));
  200.       (void) preselectfont(fptr);
  201.       setfamily(fptr);
  202.    } else {
  203.       nextstring = area;   /* remove from string pool */
  204.       (void) preselectfont(fptr);
  205.       if (fptr->scalename==NULL) {
  206.          fptr->scalename=newstring(scname);
  207.          setfamily(fptr);
  208.       }
  209.    }
  210.    includesfonts = 1;
  211.    fptr->psflag |= THISPAGE;
  212.    includechars(fptr, q);
  213. }
  214. /*
  215.  * Parse the arguments to a "%%VMusage" comment.  The Adobe Type 1 Font Format
  216.  * book specifies two arguments. This routine will accept one or two arguments;
  217.  * if there are two arguments we take the maximum.
  218.  */
  219. integer
  220. scanvm(p)
  221. char *p ;
  222. {
  223.    char* q;
  224.    integer vm, vmmax;
  225.  /*  extern long atol() ; */
  226.  
  227.    q = strtok(p, " ");
  228.    if (q==NULL) {
  229.       error("Missing data in VMusage comment");
  230.       return 0;
  231.    }
  232.    vmmax = atol(q);
  233.    q = strtok((char *)0, " ");
  234.    if (q!=NULL && (vm=atol(q))>vmmax)
  235.       vmmax = vm;
  236.    return vmmax;
  237. }
  238. /*
  239.  * Scan an initial sequence of comment lines looking for font and memory
  240.  * usage specifications.  This does not handle the "atend" construction.
  241.  */
  242. void
  243. scanfontcomments(filename)
  244. char* filename ;
  245. {
  246.    char p[500];
  247.    FILE *f;
  248.    integer truecost = pagecost ;
  249.    Boolean trueknown = 0 ;
  250.    fontdesctype *oldcf = curfnt;
  251.  
  252.    f = search(figpath, filename, READ) ;
  253.    if (f) {
  254.       while (fgets(p,500,f) && p[0]=='%' &&
  255.             (p[1]=='!' || p[1]=='%' || p[1]=='*'))
  256.          if (strncmp(p, "%*Font:", 7) == 0)
  257.             scan1fontcomment(p+7);
  258.          else if (strncmp(p, "%%VMusage:", 9) == 0) {
  259.             truecost += scanvm(p+10) ;
  260.             trueknown = 1 ;
  261.          }
  262.       if (trueknown)
  263.          pagecost = truecost ;
  264.       fclose(f) ;
  265.    }
  266.    curfnt = oldcf;
  267. }
  268. /*
  269.  * Is string s less than 30 characters long with no special characters
  270.  * that are not allowed in PostScript commands.
  271.  */
  272. Boolean
  273. okascmd(ss)
  274. char *ss ;
  275. {
  276.    register c = 0 ;
  277.    register char *s = ss ;
  278.  
  279.    while (*s)
  280.       if (*s<' ' || *s>126 || ++c==30)
  281.          return(0) ;
  282.    return(strcspn(ss,"()<>[]{}%/") == c) ;
  283. }
  284. /*
  285.  * Output font area and font name strings as a literal string
  286.  */
  287. void
  288. nameout(area, name)
  289. char *area, *name ;
  290. {
  291.    char buf[30] ;
  292.    char *s ;
  293.  
  294.    if (*area==0 && okascmd(name)) {
  295.       (void)sprintf(buf, "/%s", name) ;
  296.       cmdout(name);
  297.    } else {
  298.       for (s=area; *s; s++)
  299.          scout(*s) ;
  300.       for (s=name; *s; s++)
  301.          scout(*s) ;
  302.       stringend();
  303.       cmdout("cvn") ;
  304.    }
  305. }
  306. /*
  307.  * Output commands for defining a table of PostScript font identifiers for
  308.  * fonts used in included psfiles in the current section.
  309.  */
  310. void
  311. fonttableout()
  312. {
  313.    int i, k;
  314.    fontdesctype *f;
  315.  
  316.    for (i=0; i<nextfonthd; i++) {
  317.       for (f=fonthd[i]; f!=NULL; f=f->nextsize)
  318.          if (f->psflag==EXISTS) break;
  319.       if (f!=NULL) {
  320.          nameout(f->area, f->name);
  321.          k = 0;
  322.          do {   if (f->psflag==EXISTS) {
  323.                cmdout(f->scalename);
  324.                lfontout((int)f->psname);
  325.             }
  326.             f = f->nextsize;
  327.             k++;
  328.          } while (f!=NULL);
  329.          numout((integer)k);
  330.          cmdout("fstore");
  331.       }
  332.    }
  333. }
  334.